/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.game.math.view.domain;

import java.util.Observable;
import java.util.Observer;
import java.util.ResourceBundle;
import javax.swing.table.AbstractTableModel;
/**
 *
 * @author nmduc
 */
class ExpressionTableModel extends AbstractTableModel with Observer {

  private var examination:Examination = Examination.getInstance();
  this.examination.addObserver(this);

  def getExamination():Examination = {
    examination;
  }

  override def getRowCount():Int = {
    if (this.examination != null) {
      this.examination.expressionList.size;
    } else {
      0;
    }
  }

  override def getColumnCount():Int = {
    2;
  }

  override def getValueAt(row:Int, col:Int):Object = {

    if (!isValidatedRowIndex(row)) {
      throw new IndexOutOfBoundsException("row selected is " + row + " but cannot found in the table.");
    }
    if (!isValidatedColumnIndex(col)) {
      throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
    }
    val expressions = this.examination.expressionList.toArray;
    val  expression:MathExpression = expressions(row);
    col match {
      case 0 =>
        expression.expression;
      case _ =>
        expression.inputResult;
    }
  }

  override def getColumnClass(i:Int):Class[Object] = {
    classOf[String].asInstanceOf[Class[Object]];
  }

  override def getColumnName(col:Int):String = {
    if (isValidatedColumnIndex(col)) {
      col match {
        case 0 =>
          ExpressionTableModel.bundle.getString("col_0.name");
        case _  =>
          ExpressionTableModel.bundle.getString("col_1.name");
      }
    } else {
      throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
    }
  }

  override def isCellEditable(row:Int, col:Int):Boolean = {
    if (!isValidatedRowIndex(row)) {
      throw new IndexOutOfBoundsException("row selected is " + row + " but cannot found in the table.");
    }
    if (!isValidatedColumnIndex(col)) {
      throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
    }
    val expressions = this.examination.expressionList.toArray;
    val  expression:MathExpression = expressions(row);
    !examination.checked  && col == 1;
  }

  override def setValueAt(value:Any, row:Int, col:Int):Unit = {

    if (!isValidatedRowIndex(row)) {
      throw new IndexOutOfBoundsException("row selected is " + row + " but cannot found in the table.");
    }
    if (!isValidatedColumnIndex(col)) {
      throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
    }
    if (col != 1) {
      throw new IndexOutOfBoundsException("Only cells at column 1 can be edited");
    }
    val expressions = this.examination.expressionList.toArray;
    val expression:MathExpression = expressions(row);
    expression.inputResult = value.asInstanceOf[String];
    expression.corrected =expression.inputResult.trim().equals(expression.result);
  }

  private def isValidatedColumnIndex(col:Int):Boolean = {
    col >= 0 && col < 2;
  }

  private def isValidatedRowIndex( row:Int):Boolean = {
    row >= 0 && row < this.getRowCount();
  }

  override def update( o:Observable,  o1:Any):Unit = {
    this.fireTableDataChanged();
  }
}
object ExpressionTableModel {
  private val bundle:ResourceBundle  = ResourceBundle.getBundle("org.game.math.view.domain.ExpressionTableModel");
}